package com.tsfyun.scm.config.declare;

import com.tsfyun.common.base.config.properties.NoticeProperties;
import com.tsfyun.common.base.help.DingTalkNoticeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

@Slf4j
@Component
public class DeclareNoticeSender implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate declareRabbitTemplate;

    @Autowired
    private NoticeProperties noticeProperties;

    @PostConstruct
    public void init() {
        declareRabbitTemplate.setConfirmCallback(this);
        declareRabbitTemplate.setReturnCallback(this);
    }

    /**
     * 发送消息
     * @param exchange 交换机
     * @param routingKey 路由键
     * @param messageStr 消息体
     */
    public void send(String exchange,String routingKey,String messageStr){
        String msgId = UUID.randomUUID().toString();
        CorrelationData correlationData = new CorrelationData(msgId);
        Message message = MessageBuilder.withBody(messageStr.getBytes()).setHeader("source","saas").setCorrelationId(msgId).build();
        declareRabbitTemplate.send(exchange,routingKey,message,correlationData);
    }

    /**
     * 发送消息
     * @param exchange 交换机
     * @param routingKey 路由键
     * @param messageStr 消息体
     * @param delay 延时时间（毫秒）
     */
    public void send(String exchange,String routingKey,String messageStr,Long delay){
        String msgId = UUID.randomUUID().toString();
        CorrelationData correlationData = new CorrelationData(msgId);
        Message message = MessageBuilder.withBody(messageStr.getBytes()).setHeader("source","saas").setHeader("x-delay",delay)
                .setCorrelationId(msgId).build();
        declareRabbitTemplate.send(exchange,routingKey,message,correlationData);
    }

    /*
     * 消息从交换机成功到达队列，则returnedMessage方法不会执行
     * 消息从交换机未能成功到达队列，则returnedMessage方法会执行
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.info("消息无法被路由，被服务器退回>>>" + new String(message.getBody(), StandardCharsets.UTF_8) + ",应答码:" + replyCode
                + ",应答文本:" + replyText + ",交换机:" + exchange + ",路由键:" + routingKey);
    }

    /**
     * 发送确认
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (!ack) {
            log.error("消息发送失败，【{}】，异常内容：【{}】",correlationData.toString(),cause);
            DingTalkNoticeUtil.send2DingDingOtherException("MQ消息发送失败",cause,null,noticeProperties.getDingdingUrl());
        } else {
            log.info("消息发送成功，【{}】】",correlationData.toString());
        }
    }
}